home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Games / SpriteFight 2002 v2.0a1 / Sprite.c < prev    next >
Text File  |  1994-04-26  |  26KB  |  974 lines

  1. ///--------------------------------------------------------------------------------------
  2. //    Sprite.c
  3. //
  4. //    Created:    Tuesday, October, 1992 at 10:10:06 PM
  5. //    By:        Tony Myles
  6. //
  7. //    Copyright: © 1991-94 Tony Myles, All rights reserved worldwide
  8. //
  9. //    Description:    implementation of the sprites
  10. ///--------------------------------------------------------------------------------------
  11.  
  12.  
  13. #ifndef __SWCOMMON__
  14. #include "SWCommonHeaders.h"
  15. #endif
  16.  
  17. #ifndef __MEMORY__
  18. #include <Memory.h>
  19. #endif
  20.  
  21. #ifndef __SPRITEWORLDUTILS__
  22. #include "SpriteWorldUtils.h"
  23. #endif
  24.  
  25. #ifndef __SPRITEWORLD__
  26. #include "SpriteWorld.h"
  27. #endif
  28.  
  29. #ifndef __SPRITE__
  30. #include "Sprite.h"
  31. #endif
  32.  
  33. #ifndef __FRAME__
  34. #include "Frame.h"
  35. #endif
  36.  
  37. #if MPW
  38. #pragma segment SpriteWorld
  39. #endif
  40.  
  41.  
  42. ///--------------------------------------------------------------------------------------
  43. //    SWCreateSprite
  44. ///--------------------------------------------------------------------------------------
  45.  
  46. SW_FUNC OSErr SWCreateSprite(
  47.     SpritePtr* newSpriteP,
  48.     void* spriteStorageP,
  49.     short maxFrames)
  50. {
  51.     OSErr err = noErr;
  52.     SpritePtr tempSpriteP;
  53.     Size frameArraySize;
  54.  
  55.     *newSpriteP = NULL;
  56.  
  57.     tempSpriteP = (SpritePtr) (spriteStorageP == NULL) ? NewPtr(sizeof(SpriteRec)) : spriteStorageP;
  58.  
  59.     if (tempSpriteP != NULL)
  60.     {
  61.         frameArraySize = (Size)(maxFrames * sizeof(FramePtr));
  62.  
  63.         tempSpriteP->frameArray = (FramePtr *)NewPtrClear(frameArraySize);
  64.  
  65.         if (tempSpriteP->frameArray != NULL)
  66.         {
  67.             tempSpriteP->nextSpriteP = NULL;
  68.             tempSpriteP->prevSpriteP = NULL;
  69.  
  70.                 // initialize drawing fields
  71.             tempSpriteP->isVisible = true;
  72.             tempSpriteP->needsToBeDrawn = true;
  73.             tempSpriteP->needsToBeErased = false;
  74.             tempSpriteP->destFrameRect.left = 0;
  75.             tempSpriteP->destFrameRect.top = 0;
  76.             tempSpriteP->destFrameRect.right = 0;
  77.             tempSpriteP->destFrameRect.bottom = 0;
  78.             tempSpriteP->oldFrameRect.left = 0;
  79.             tempSpriteP->oldFrameRect.top = 0;
  80.             tempSpriteP->oldFrameRect.right = 0;
  81.             tempSpriteP->oldFrameRect.bottom = 0;
  82.             tempSpriteP->deltaFrameRect.left = 0;
  83.             tempSpriteP->deltaFrameRect.top = 0;
  84.             tempSpriteP->deltaFrameRect.right = 0;
  85.             tempSpriteP->deltaFrameRect.bottom = 0;
  86.             tempSpriteP->screenMaskRgn = NULL;
  87.             tempSpriteP->frameDrawProc = SWStdDrawProc;
  88.  
  89.                 // initialize frame fields
  90.             tempSpriteP->frameTimeTask.timeTask.tmAddr = NewTimerProc(SWTimeTask);
  91.             tempSpriteP->frameTimeTask.timeTask.qLink = NULL;
  92.             tempSpriteP->frameTimeTask.timeTask.qType = 0;
  93.             tempSpriteP->frameTimeTask.timeTask.tmCount = 0;
  94.             tempSpriteP->frameTimeTask.timeTask.tmWakeUp = 0;
  95.             tempSpriteP->frameTimeTask.timeTask.tmReserved = 0;
  96.             tempSpriteP->frameTimeTask.hasTaskFired = false;
  97.             tempSpriteP->curFrameP = NULL;
  98.             tempSpriteP->numFrames = 0;
  99.             tempSpriteP->maxFrames = maxFrames;
  100.             tempSpriteP->frameTimeInterval = -1;
  101.             tempSpriteP->frameAdvance = 1;
  102.             tempSpriteP->curFrameIndex = 0;
  103.             tempSpriteP->firstFrameIndex = 0;
  104.             tempSpriteP->lastFrameIndex = 0;
  105.             tempSpriteP->frameChangeProc = NULL;
  106.  
  107.                 // initialize movement fields
  108.             tempSpriteP->moveTimeTask.timeTask.tmAddr = NewTimerProc(SWTimeTask);
  109.             tempSpriteP->moveTimeTask.timeTask.qLink = NULL;
  110.             tempSpriteP->moveTimeTask.timeTask.qType = 0;
  111.             tempSpriteP->moveTimeTask.timeTask.tmCount = 0;
  112.             tempSpriteP->moveTimeTask.timeTask.tmWakeUp = 0;
  113.             tempSpriteP->moveTimeTask.timeTask.tmReserved = 0;
  114.             tempSpriteP->moveTimeTask.hasTaskFired = true;
  115.             tempSpriteP->moveTimeInterval = 0;
  116.             tempSpriteP->horizMoveDelta = 0;
  117.             tempSpriteP->vertMoveDelta = 0;
  118.             tempSpriteP->moveBoundsRect.left = 0;
  119.             tempSpriteP->moveBoundsRect.top = 0;
  120.             tempSpriteP->moveBoundsRect.right = 0;
  121.             tempSpriteP->moveBoundsRect.bottom = 0;
  122.             tempSpriteP->spriteMoveProc = NULL;
  123.  
  124.                 // collision detection fields
  125.             tempSpriteP->collideRect.left = 0;
  126.             tempSpriteP->collideRect.top = 0;
  127.             tempSpriteP->collideRect.right = 0;
  128.             tempSpriteP->collideRect.bottom = 0;
  129.             tempSpriteP->spriteCollideProc = NULL;
  130.  
  131.             tempSpriteP->userData = 0;
  132.  
  133.                 // insert the sprite time tasks into the time manager queue
  134.             InsTime((QElemPtr)&tempSpriteP->moveTimeTask);
  135.             InsTime((QElemPtr)&tempSpriteP->frameTimeTask);
  136.  
  137.                 // the sprite has been successfully created
  138.             *newSpriteP = tempSpriteP;
  139.         }
  140.         else
  141.         {
  142.             err = MemError();
  143.  
  144.             DisposePtr((Ptr)tempSpriteP);
  145.         }
  146.     }
  147.     else
  148.     {
  149.         err = MemError();
  150.     }
  151.  
  152.     return err;
  153. }
  154.  
  155.  
  156. ///--------------------------------------------------------------------------------------
  157. //    SWCreateSpriteFromCIconResource
  158. ///--------------------------------------------------------------------------------------
  159.  
  160. SW_FUNC OSErr SWCreateSpriteFromCIconResource(
  161.     SpritePtr* newSpriteP,
  162.     void* spriteStorageP,
  163.     short cIconID,
  164.     short maxFrames,
  165.     MaskType maskType)
  166. {
  167.     OSErr err;
  168.     SpritePtr tempSpriteP;
  169.     FramePtr newFrameP;
  170.     short frame;
  171.  
  172.     *newSpriteP = NULL;
  173.  
  174.     err = SWCreateSprite(&tempSpriteP, spriteStorageP, maxFrames);
  175.  
  176.     if (err == noErr)
  177.     {
  178.         for (frame = 0; frame < maxFrames; frame++)
  179.         {
  180.             err = SWCreateFrameFromCIconResource(&newFrameP, cIconID + frame, maskType);
  181.  
  182.             if (err == noErr)
  183.             {
  184.                 err = SWAddFrame(tempSpriteP, newFrameP);
  185.             }
  186.  
  187.             if (err != noErr)
  188.             {
  189.                 SWDisposeFrame(newFrameP);
  190.                 SWDisposeSprite(tempSpriteP);
  191.                 break;
  192.             }
  193.         }
  194.  
  195.         if (err == noErr)
  196.         {
  197.             SWSetSpriteFrameRange(tempSpriteP, 0, maxFrames - 1);
  198.  
  199.             *newSpriteP = tempSpriteP;
  200.         }
  201.     }
  202.  
  203.     return err;
  204. }
  205.  
  206.  
  207. ///--------------------------------------------------------------------------------------
  208. //    SWCreateSpriteFromPictResource
  209. ///--------------------------------------------------------------------------------------
  210.  
  211. SW_FUNC OSErr SWCreateSpriteFromPictResource(
  212.     SpritePtr* newSpriteP,
  213.     void* spriteStorageP,
  214.     short pictResID,
  215.     short maskResID,
  216.     short maxFrames,
  217.     MaskType maskType)
  218. {
  219.     OSErr err;
  220.     SpritePtr tempSpriteP;
  221.     FramePtr newFrameP;
  222.     short frame;
  223.  
  224.     *newSpriteP = NULL;
  225.  
  226.     err = SWCreateSprite(&tempSpriteP, spriteStorageP, maxFrames);
  227.  
  228.     if (err == noErr)
  229.     {
  230.         for (frame = 0; frame < maxFrames; frame++)
  231.         {
  232.             err = SWCreateFrameFromPictResource(&newFrameP, pictResID + frame, maskResID + frame, maskType);
  233.  
  234.             if (err == noErr)
  235.             {
  236.                 err = SWAddFrame(tempSpriteP, newFrameP);
  237.             }
  238.  
  239.             if (err != noErr)
  240.             {
  241.                 SWDisposeFrame(newFrameP);
  242.                 SWDisposeSprite(tempSpriteP);
  243.                 break;
  244.             }
  245.         }
  246.  
  247.         if (err == noErr)
  248.         {
  249.             SWSetSpriteFrameRange(tempSpriteP, 0, maxFrames - 1);
  250.  
  251.             *newSpriteP = tempSpriteP;
  252.         }
  253.     }
  254.     
  255.     return err;
  256. }
  257.  
  258.  
  259. ///--------------------------------------------------------------------------------------
  260. //    SWCloneSprite
  261. ///--------------------------------------------------------------------------------------
  262.  
  263. SW_FUNC OSErr SWCloneSprite(
  264.     SpritePtr cloneSpriteP,
  265.     SpritePtr* newSpriteP,
  266.     void* spriteStorageP)
  267. {
  268.     OSErr err;
  269.     SpritePtr tempSpriteP;
  270.     TimeTaskRec moveTimeTask, frameTimeTask;
  271.     short frame;
  272.     FramePtr* tempFrameArray;
  273.  
  274.     err = SWCreateSprite(&tempSpriteP, spriteStorageP, cloneSpriteP->maxFrames);
  275.  
  276.     if (err == noErr)
  277.     {
  278.             // save off the fields that are unique to a particular sprite
  279.         moveTimeTask = tempSpriteP->moveTimeTask;
  280.         frameTimeTask = tempSpriteP->frameTimeTask;
  281.         tempFrameArray = tempSpriteP->frameArray;
  282.  
  283.             // copy the clone sprite into the temp sprite
  284.         *tempSpriteP = *cloneSpriteP;
  285.  
  286.             // restore the unique fields
  287.         tempSpriteP->moveTimeTask = moveTimeTask;
  288.         tempSpriteP->frameTimeTask = frameTimeTask;
  289.         tempSpriteP->frameArray = tempFrameArray;
  290.  
  291.             // clear the next and prev fields, just in case
  292.         tempSpriteP->nextSpriteP = NULL;
  293.         tempSpriteP->prevSpriteP = NULL;
  294.  
  295.             // copy the frame array
  296.         for (frame = 0; frame < tempSpriteP->maxFrames; frame++)
  297.         {
  298.             tempSpriteP->frameArray[frame] = cloneSpriteP->frameArray[frame];
  299.             tempSpriteP->frameArray[frame]->useCount++;
  300.         }
  301.  
  302.         *newSpriteP = tempSpriteP;
  303.     }
  304.  
  305.     return err;
  306. }
  307.  
  308.  
  309. ///--------------------------------------------------------------------------------------
  310. //    SWDisposeSprite
  311. ///--------------------------------------------------------------------------------------
  312.  
  313. SW_FUNC void SWDisposeSprite(
  314.     SpritePtr deadSpriteP)
  315. {
  316.     SWCloseSprite(deadSpriteP);
  317.  
  318.     DisposePtr((Ptr)deadSpriteP);
  319. }
  320.  
  321.  
  322. ///--------------------------------------------------------------------------------------
  323. //    SWCloseSprite
  324. ///--------------------------------------------------------------------------------------
  325.  
  326. SW_FUNC void SWCloseSprite(
  327.     SpritePtr deadSpriteP)
  328. {
  329.     short frame;
  330.  
  331.     if (deadSpriteP != NULL)
  332.     {
  333.             // remove the sprite time tasks from the time manager queue
  334.         RmvTime((QElemPtr)&deadSpriteP->moveTimeTask);
  335.         RmvTime((QElemPtr)&deadSpriteP->frameTimeTask);
  336.  
  337. #if SW_PPC
  338.         DisposeRoutineDescriptor(deadSpriteP->moveTimeTask.timeTask.tmAddr);
  339.         DisposeRoutineDescriptor(deadSpriteP->frameTimeTask.timeTask.tmAddr);
  340. #endif
  341.  
  342.  
  343.         for (frame = 0; frame < deadSpriteP->numFrames; frame++)
  344.         {
  345.             SWDisposeFrame(deadSpriteP->frameArray[frame]);
  346.         }
  347.  
  348.         DisposePtr((Ptr)deadSpriteP->frameArray);
  349.     }
  350. }
  351.  
  352.  
  353. ///--------------------------------------------------------------------------------------
  354. //    SWLockSprite
  355. ///--------------------------------------------------------------------------------------
  356.  
  357. SW_FUNC void SWLockSprite(
  358.     SpritePtr srcSpriteP)
  359. {
  360.     register long numFrames;
  361.  
  362.         // is the sprite not locked?
  363.     numFrames = srcSpriteP->numFrames;
  364.  
  365.     while (numFrames--)
  366.     {
  367.         SWLockFrame(srcSpriteP->frameArray[numFrames]);
  368.     }
  369. }
  370.  
  371.  
  372. ///--------------------------------------------------------------------------------------
  373. //    SWUnlockSprite
  374. ///--------------------------------------------------------------------------------------
  375.  
  376. SW_FUNC void SWUnlockSprite(
  377.     SpritePtr srcSpriteP)
  378. {
  379.     register long numFrames;
  380.  
  381.         // is the sprite locked?
  382.     numFrames = srcSpriteP->numFrames;
  383.  
  384.     while (numFrames--)
  385.     {
  386.         SWUnlockFrame(srcSpriteP->frameArray[numFrames]);
  387.     }
  388. }
  389.  
  390.  
  391. ///--------------------------------------------------------------------------------------
  392. //    SWSetSpriteDrawProc
  393. ///--------------------------------------------------------------------------------------
  394.  
  395. SW_FUNC void SWSetSpriteDrawProc(
  396.     SpritePtr srcSpriteP,
  397.     DrawProcPtr drawProc)
  398. {
  399.     srcSpriteP->frameDrawProc = drawProc;
  400. }
  401.  
  402.  
  403. ///--------------------------------------------------------------------------------------
  404. //    SWStdDrawProc
  405. ///--------------------------------------------------------------------------------------
  406.  
  407. SW_FUNC void SWStdDrawProc(
  408.     FramePtr srcFrameP,
  409.     FramePtr dstFrameP,
  410.     Rect* srcRect,
  411.     Rect* dstRect)
  412. {
  413.         // by the way, CopyBits with a mask region is 60% faster than CopyMask!
  414.     CopyBits((BitMapPtr)srcFrameP->framePix.pixMapP, (BitMapPtr)dstFrameP->framePix.pixMapP,
  415.                 srcRect, dstRect, srcCopy, srcFrameP->maskRgn);
  416. }
  417.  
  418.  
  419. ///--------------------------------------------------------------------------------------
  420. //    SWAddFrame
  421. ///--------------------------------------------------------------------------------------
  422.  
  423. SW_FUNC OSErr SWAddFrame(
  424.     SpritePtr srcSpriteP,
  425.     FramePtr newFrameP)
  426. {
  427.     OSErr err = noErr;
  428.  
  429.         // don’t exceed maximum number of frames
  430.     if (srcSpriteP->numFrames < srcSpriteP->maxFrames)
  431.     {
  432.         srcSpriteP->frameArray[srcSpriteP->numFrames] = newFrameP;
  433.  
  434.             // increment the number of frames
  435.         srcSpriteP->numFrames++;
  436.         newFrameP->useCount++;
  437.  
  438.         SWSetCurrentFrame(srcSpriteP, srcSpriteP->frameArray[0]);
  439.     }
  440.     else
  441.     {
  442.         err = kMaxFramesErr;
  443.     }
  444.  
  445.     return err;
  446. }
  447.  
  448.  
  449. ///--------------------------------------------------------------------------------------
  450. //    SWRemoveFrame
  451. ///--------------------------------------------------------------------------------------
  452.  
  453. SW_FUNC void SWRemoveFrame(
  454.     SpritePtr srcSpriteP,
  455.     FramePtr oldFrameP)
  456. {
  457.     register long numFrames;
  458.     register FramePtr *frameArray;
  459.  
  460.     numFrames = srcSpriteP->numFrames;
  461.     frameArray = srcSpriteP->frameArray;
  462.  
  463.     oldFrameP->useCount--;
  464.  
  465.         // find the frame to be removed
  466.     while (numFrames--)
  467.     {
  468.         if (frameArray[numFrames] == oldFrameP)
  469.         {
  470.                 // move the rest of the frames down
  471.             while (numFrames < (srcSpriteP->numFrames - 1L))
  472.             {
  473.                 frameArray[numFrames] = frameArray[numFrames + 1L];
  474.  
  475.                 numFrames++;
  476.             }
  477.  
  478.             break;
  479.         }
  480.     }
  481. }
  482.  
  483.  
  484. ///--------------------------------------------------------------------------------------
  485. //    SWSetCurrentFrame
  486. ///--------------------------------------------------------------------------------------
  487.  
  488. SW_FUNC void SWSetCurrentFrame(
  489.     SpritePtr srcSpriteP,
  490.     FramePtr newFrameP)
  491. {
  492.     Rect lastRect;
  493.     short horizOffset, vertOffset;
  494.     short frameIndex = 0;
  495.  
  496.     if (srcSpriteP->curFrameP != newFrameP)
  497.     {
  498.         srcSpriteP->curFrameP = newFrameP;
  499.  
  500.         lastRect = srcSpriteP->destFrameRect;
  501.  
  502.         srcSpriteP->destFrameRect = newFrameP->frameRect;
  503.  
  504.         horizOffset = (lastRect.left - srcSpriteP->destFrameRect.left);
  505.         vertOffset = (lastRect.top - srcSpriteP->destFrameRect.top);
  506.  
  507.         srcSpriteP->destFrameRect.left += horizOffset;
  508.         srcSpriteP->destFrameRect.right += horizOffset;
  509.         srcSpriteP->destFrameRect.top += vertOffset;
  510.         srcSpriteP->destFrameRect.bottom += vertOffset;
  511.  
  512.             // this really lame search is performed so we set the
  513.             // frame index of the sprite properly, which could
  514.             // prevent strange behavior later on. The lesson to be learned
  515.             // here is to call SWSetCurrentFrameIndex instead.
  516.         for (frameIndex = 0; frameIndex < srcSpriteP->numFrames; frameIndex++)
  517.         {
  518.             if (srcSpriteP->frameArray[frameIndex] == newFrameP)
  519.             {
  520.                 srcSpriteP->curFrameIndex = frameIndex;
  521.                 break;
  522.             }
  523.         }
  524.  
  525.         srcSpriteP->needsToBeDrawn = true;
  526.     }
  527. }
  528.  
  529.  
  530. ///--------------------------------------------------------------------------------------
  531. //    SWSetCurrentFrameIndex
  532. ///--------------------------------------------------------------------------------------
  533.  
  534. SW_FUNC void SWSetCurrentFrameIndex(
  535.     SpritePtr srcSpriteP,
  536.     short frameIndex)
  537. {
  538.     register FramePtr newFrameP;
  539.     Rect lastRect;
  540.     short horizOffset, vertOffset;
  541.  
  542.     if (frameIndex < srcSpriteP->numFrames)
  543.     {
  544.         newFrameP = srcSpriteP->frameArray[frameIndex];
  545.  
  546.         srcSpriteP->curFrameP = newFrameP;
  547.  
  548.         lastRect = srcSpriteP->destFrameRect;
  549.  
  550.         srcSpriteP->destFrameRect = newFrameP->frameRect;
  551.  
  552.         horizOffset = (lastRect.left - srcSpriteP->destFrameRect.left);
  553.         vertOffset = (lastRect.top - srcSpriteP->destFrameRect.top);
  554.  
  555.         srcSpriteP->destFrameRect.left += horizOffset;
  556.         srcSpriteP->destFrameRect.right += horizOffset;
  557.         srcSpriteP->destFrameRect.top += vertOffset;
  558.         srcSpriteP->destFrameRect.bottom += vertOffset;
  559.  
  560.         srcSpriteP->curFrameIndex = frameIndex;
  561.  
  562.         srcSpriteP->needsToBeDrawn = true;
  563.     }
  564. }
  565.  
  566.  
  567. ///--------------------------------------------------------------------------------------
  568. //    SWSetSpriteFrameAdvance
  569. ///--------------------------------------------------------------------------------------
  570.  
  571. SW_FUNC void SWSetSpriteFrameAdvance(
  572.     SpritePtr srcSpriteP,
  573.     short frameAdvance)
  574. {
  575.     srcSpriteP->frameAdvance = frameAdvance;
  576. }
  577.  
  578.  
  579. ///--------------------------------------------------------------------------------------
  580. //    SWSetSpriteFrameRange
  581. ///--------------------------------------------------------------------------------------
  582.  
  583. SW_FUNC void SWSetSpriteFrameRange(
  584.     SpritePtr srcSpriteP,
  585.     short firstFrameIndex,
  586.     short lastFrameIndex)
  587. {
  588.     srcSpriteP->firstFrameIndex = firstFrameIndex;
  589.     srcSpriteP->lastFrameIndex = lastFrameIndex;
  590. }
  591.  
  592.  
  593. ///--------------------------------------------------------------------------------------
  594. //    SWSetSpriteFrameTime
  595. ///--------------------------------------------------------------------------------------
  596.  
  597. SW_FUNC void SWSetSpriteFrameTime(
  598.     SpritePtr srcSpriteP,
  599.     long timeInterval)
  600. {
  601.     srcSpriteP->frameTimeInterval = timeInterval;
  602.  
  603.         // is the time interval positive?
  604.     if (timeInterval > 0)
  605.     {
  606.             // if the task is not already primed…
  607.         if (!SWIsTaskPrimed(&srcSpriteP->frameTimeTask.timeTask))
  608.         {
  609.                 // …prime it
  610.             srcSpriteP->frameTimeTask.hasTaskFired = true;
  611.         }
  612.     }
  613.         // is the time interval negative?
  614.     else if (timeInterval < 0)
  615.     {
  616.             // if the task is primed…
  617.         if (SWIsTaskPrimed(&srcSpriteP->frameTimeTask.timeTask))
  618.         {
  619.                 // …remove it
  620.             RmvTime((QElemPtr)&srcSpriteP->frameTimeTask);
  621.             InsTime((QElemPtr)&srcSpriteP->frameTimeTask);
  622.         }
  623.  
  624.             // the timeInterval is negative, which means never change the frame
  625.         srcSpriteP->frameTimeTask.hasTaskFired = false;
  626.     }
  627.         // is the time interval zero?
  628.     else
  629.     {
  630.             // this means change frames as quickly as possible
  631.         srcSpriteP->frameTimeTask.hasTaskFired = true;
  632.     }
  633. }
  634.  
  635.  
  636. ///--------------------------------------------------------------------------------------
  637. //    SWSetSpriteFrameProc
  638. ///--------------------------------------------------------------------------------------
  639.  
  640. SW_FUNC void SWSetSpriteFrameProc(
  641.     SpritePtr srcSpriteP,
  642.     FrameProcPtr frameProc)
  643. {
  644.     srcSpriteP->frameChangeProc = frameProc;
  645. }
  646.  
  647.  
  648. ///--------------------------------------------------------------------------------------
  649. //    SWMoveSprite
  650. ///--------------------------------------------------------------------------------------
  651.  
  652. SW_FUNC void SWMoveSprite(
  653.     SpritePtr srcSpriteP,
  654.     short horizLoc,
  655.     short vertLoc)
  656. {
  657.     if ((horizLoc != 0) || (vertLoc != 0))
  658.     {
  659.         srcSpriteP->destFrameRect.bottom = vertLoc + (srcSpriteP->destFrameRect.bottom -
  660.                                                     srcSpriteP->destFrameRect.top);
  661.         srcSpriteP->destFrameRect.right = horizLoc + (srcSpriteP->destFrameRect.right -
  662.                                                     srcSpriteP->destFrameRect.left);
  663.         srcSpriteP->destFrameRect.top = vertLoc;
  664.         srcSpriteP->destFrameRect.left = horizLoc;
  665.  
  666.         srcSpriteP->needsToBeDrawn = true;
  667.     }
  668. }
  669.  
  670.  
  671. ///--------------------------------------------------------------------------------------
  672. //    SWOffsetSprite
  673. ///--------------------------------------------------------------------------------------
  674.  
  675. SW_FUNC void SWOffsetSprite(
  676.     SpritePtr srcSpriteP,
  677.     short horizDelta,
  678.     short vertDelta)
  679. {
  680.     if ((horizDelta != 0) || (vertDelta != 0))
  681.     {
  682.         srcSpriteP->destFrameRect.right += horizDelta;
  683.         srcSpriteP->destFrameRect.bottom += vertDelta;
  684.         srcSpriteP->destFrameRect.left += horizDelta;
  685.         srcSpriteP->destFrameRect.top += vertDelta;
  686.  
  687.         srcSpriteP->needsToBeDrawn = true;
  688.     }
  689. }
  690.  
  691.  
  692. ///--------------------------------------------------------------------------------------
  693. //    SWSetSpriteLocation
  694. ///--------------------------------------------------------------------------------------
  695.  
  696. SW_FUNC void SWSetSpriteLocation(
  697.     SpritePtr srcSpriteP,
  698.     short horizLoc,
  699.     short vertLoc)
  700. {
  701.     srcSpriteP->destFrameRect.bottom = vertLoc + (srcSpriteP->destFrameRect.bottom -
  702.                                                 srcSpriteP->destFrameRect.top);
  703.     srcSpriteP->destFrameRect.right = horizLoc + (srcSpriteP->destFrameRect.right -
  704.                                                 srcSpriteP->destFrameRect.left);
  705.     srcSpriteP->destFrameRect.top = vertLoc;
  706.     srcSpriteP->destFrameRect.left = horizLoc;
  707.  
  708.     srcSpriteP->deltaFrameRect = srcSpriteP->destFrameRect;
  709.     srcSpriteP->oldFrameRect = srcSpriteP->destFrameRect;
  710. }
  711.  
  712.  
  713. ///--------------------------------------------------------------------------------------
  714. //    SWSetSpriteMoveBounds
  715. ///--------------------------------------------------------------------------------------
  716.  
  717. SW_FUNC void SWSetSpriteMoveBounds(
  718.     SpritePtr srcSpriteP,
  719.     Rect* moveBoundsRect)
  720. {
  721.     srcSpriteP->moveBoundsRect = *moveBoundsRect;
  722. }
  723.  
  724.  
  725. ///--------------------------------------------------------------------------------------
  726. //    SWSetSpriteMoveDelta
  727. ///--------------------------------------------------------------------------------------
  728.  
  729. SW_FUNC void SWSetSpriteMoveDelta(
  730.     SpritePtr srcSpriteP,
  731.     short horizDelta,
  732.     short vertDelta)
  733. {
  734.         // set sprite’s velocity
  735.     srcSpriteP->horizMoveDelta = horizDelta;
  736.     srcSpriteP->vertMoveDelta = vertDelta;
  737. }
  738.  
  739.  
  740. ///--------------------------------------------------------------------------------------
  741. //    SWSetSpriteMoveTime
  742. ///--------------------------------------------------------------------------------------
  743.  
  744. SW_FUNC void SWSetSpriteMoveTime(
  745.     SpritePtr srcSpriteP,
  746.     long timeInterval)
  747. {
  748.     srcSpriteP->moveTimeInterval = timeInterval;
  749.  
  750.         // is the time interval positive?
  751.     if (timeInterval > 0)
  752.     {
  753.             // if the task is not already primed…
  754.         if (!SWIsTaskPrimed(&srcSpriteP->moveTimeTask.timeTask))
  755.         {
  756.                 // …prime it
  757.             srcSpriteP->moveTimeTask.hasTaskFired = true;
  758.         }
  759.     }
  760.         // is the time interval negative?
  761.     else if (timeInterval < 0)
  762.     {
  763.             // if the task is primed…
  764.         if (SWIsTaskPrimed(&srcSpriteP->moveTimeTask.timeTask))
  765.         {
  766.                 // …remove it
  767.             RmvTime((QElemPtr)&srcSpriteP->moveTimeTask);
  768.             InsTime((QElemPtr)&srcSpriteP->moveTimeTask);
  769.         }
  770.  
  771.             // the timeInterval is negative, which means never change the frame
  772.         srcSpriteP->moveTimeTask.hasTaskFired = false;
  773.     }
  774.         // is the time interval zero?
  775.     else
  776.     {
  777.             // this means change frames as quickly as possible
  778.         srcSpriteP->moveTimeTask.hasTaskFired = true;
  779.     }
  780. }
  781.  
  782.  
  783. ///--------------------------------------------------------------------------------------
  784. //    SWSetSpriteMoveProc
  785. ///--------------------------------------------------------------------------------------
  786.  
  787. SW_FUNC void SWSetSpriteMoveProc(
  788.     SpritePtr srcSpriteP,
  789.     MoveProcPtr moveProc)
  790. {
  791.     srcSpriteP->spriteMoveProc = moveProc;
  792. }
  793.  
  794.  
  795. ///--------------------------------------------------------------------------------------
  796. //    SWBounceSpriteMoveProc
  797. ///--------------------------------------------------------------------------------------
  798.  
  799. SW_FUNC void SWBounceSpriteMoveProc(
  800.     SpritePtr srcSpriteP,
  801.     Point* spritePoint)
  802. {
  803.     if (srcSpriteP->destFrameRect.left < srcSpriteP->moveBoundsRect.left)
  804.     {
  805.         srcSpriteP->horizMoveDelta = -srcSpriteP->horizMoveDelta;
  806.         spritePoint->h = srcSpriteP->moveBoundsRect.left;
  807.     }
  808.     else if (srcSpriteP->destFrameRect.right > srcSpriteP->moveBoundsRect.right)
  809.     {
  810.         srcSpriteP->horizMoveDelta = -srcSpriteP->horizMoveDelta;
  811.         spritePoint->h = srcSpriteP->moveBoundsRect.right -
  812.             (srcSpriteP->curFrameP->frameRect.right - srcSpriteP->curFrameP->frameRect.left);
  813.     }
  814.  
  815.     if (srcSpriteP->destFrameRect.top < srcSpriteP->moveBoundsRect.top)
  816.     {
  817.         srcSpriteP->vertMoveDelta = -srcSpriteP->vertMoveDelta;
  818.         spritePoint->v = srcSpriteP->moveBoundsRect.top;
  819.     }
  820.     else if (srcSpriteP->destFrameRect.bottom > srcSpriteP->moveBoundsRect.bottom)
  821.     {
  822.         srcSpriteP->vertMoveDelta = -srcSpriteP->vertMoveDelta;
  823.         spritePoint->v = srcSpriteP->moveBoundsRect.bottom -
  824.             (srcSpriteP->curFrameP->frameRect.bottom - srcSpriteP->curFrameP->frameRect.top);
  825.     }
  826. }
  827.  
  828.  
  829. ///--------------------------------------------------------------------------------------
  830. //    SWWrapSpriteMoveProc
  831. ///--------------------------------------------------------------------------------------
  832.  
  833. SW_FUNC void SWWrapSpriteMoveProc(
  834.     SpritePtr srcSpriteP,
  835.     Point* spritePoint)
  836. {
  837.     Point oldSpritePoint = *spritePoint;
  838.  
  839.     if (srcSpriteP->destFrameRect.left > srcSpriteP->moveBoundsRect.right)
  840.     {
  841.         spritePoint->h = srcSpriteP->moveBoundsRect.left -
  842.                                 (srcSpriteP->destFrameRect.right - 
  843.                                 srcSpriteP->destFrameRect.left);
  844.     }
  845.     else if (srcSpriteP->destFrameRect.right < srcSpriteP->moveBoundsRect.left)
  846.     {
  847.         spritePoint->h = srcSpriteP->moveBoundsRect.right;
  848.     }
  849.  
  850.     if (srcSpriteP->destFrameRect.top > srcSpriteP->moveBoundsRect.bottom)
  851.     {
  852.         spritePoint->v = srcSpriteP->moveBoundsRect.top -
  853.                                 (srcSpriteP->destFrameRect.bottom - 
  854.                                 srcSpriteP->destFrameRect.top);
  855.     }
  856.     else if (srcSpriteP->destFrameRect.bottom < srcSpriteP->moveBoundsRect.top)
  857.     {
  858.         spritePoint->v = srcSpriteP->moveBoundsRect.bottom;
  859.     }
  860.  
  861.     if ((spritePoint->h != oldSpritePoint.h) || (spritePoint->v != oldSpritePoint.v))
  862.     {
  863.         SWSetSpriteLocation(srcSpriteP, spritePoint->h, spritePoint->v);
  864.     }    
  865. }
  866.  
  867.  
  868. ///--------------------------------------------------------------------------------------
  869. //    SWSetSpriteCollideProc
  870. ///--------------------------------------------------------------------------------------
  871.  
  872. SW_FUNC void SWSetSpriteCollideProc(
  873.     SpritePtr srcSpriteP,
  874.     CollideProcPtr collideProc)
  875. {
  876.     srcSpriteP->spriteCollideProc = collideProc;
  877. }
  878.  
  879.  
  880. ///--------------------------------------------------------------------------------------
  881. //    SWSetSpriteVisible
  882. ///--------------------------------------------------------------------------------------
  883.  
  884. SW_FUNC void SWSetSpriteVisible(
  885.     SpritePtr srcSpriteP,
  886.     Boolean isVisible)
  887. {
  888.     srcSpriteP->isVisible = isVisible;
  889.     srcSpriteP->needsToBeDrawn = true;
  890.     srcSpriteP->needsToBeErased = !isVisible;
  891. }
  892.  
  893.  
  894. ///--------------------------------------------------------------------------------------
  895. //    SWIsSpriteInRect
  896. ///--------------------------------------------------------------------------------------
  897.  
  898. SW_FUNC Boolean SWIsSpriteInRect(
  899.     SpritePtr srcSpriteP,
  900.     Rect* testRect)
  901. {
  902.     return ((srcSpriteP->destFrameRect.top < testRect->bottom) &&
  903.             (srcSpriteP->destFrameRect.bottom > testRect->top) &&
  904.              (srcSpriteP->destFrameRect.left < testRect->right) &&
  905.              (srcSpriteP->destFrameRect.right > testRect->left));
  906. }
  907.  
  908.  
  909. ///--------------------------------------------------------------------------------------
  910. //    SWIsPointInSprite
  911. ///--------------------------------------------------------------------------------------
  912.  
  913. SW_FUNC Boolean SWIsPointInSprite(
  914.     SpritePtr srcSpriteP,
  915.     Point testPoint)
  916. {
  917.     return    (testPoint.h >= srcSpriteP->destFrameRect.left) &&
  918.             (testPoint.h <= srcSpriteP->destFrameRect.right) &&
  919.             (testPoint.v >= srcSpriteP->destFrameRect.top) &&
  920.             (testPoint.v <= srcSpriteP->destFrameRect.bottom);
  921. }
  922.  
  923.  
  924. ///--------------------------------------------------------------------------------------
  925. //    SWTimeTask
  926. ///--------------------------------------------------------------------------------------
  927.  
  928. #if defined(powerc) || defined(__powerc)
  929.  
  930. pascal void SWTimeTask(
  931.     TMTaskPtr tmTaskPtr)
  932. {
  933.     (*(TimeTaskPtr)tmTaskPtr).hasTaskFired = true;
  934. }
  935.  
  936. #else    // 68k
  937. #if THINK_C
  938.  
  939. pascal void SWTimeTask(void)
  940. {
  941.     asm
  942.     {
  943.         move.b #0x01, TimeTaskRec.hasTaskFired(A1)
  944.     }
  945. }
  946.  
  947. #else    // MetroWerks or MPW
  948.  
  949.     // %%% this inline needs to be updated if the TimeTaskRec structure ever changes
  950.     // move.b #0x01, TimeTaskRec.hasTaskFired(A1)
  951.  
  952. void SWSetTaskHasFired() = { 0x137C, 0x0001, 0x0016 }; 
  953.  
  954. pascal void SWTimeTask(void)
  955. {
  956.     SWSetTaskHasFired();
  957. }
  958.  
  959. #endif
  960. #endif
  961.  
  962.  
  963.  
  964. ///--------------------------------------------------------------------------------------
  965. //    SWIsTaskPrimed
  966. ///--------------------------------------------------------------------------------------
  967.  
  968. SW_FUNC Boolean SWIsTaskPrimed(
  969.     TMTask* tmTaskP)
  970. {
  971.     return (tmTaskP->qType & 0x8000) != 0;
  972. }
  973.  
  974.